package com.suzhe.ymall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suzhe.ymall.common.enums.MessageStatusEnum;
import com.suzhe.ymall.common.enums.TopicEnum;
import com.suzhe.ymall.common.message.OrderRollbackMessage;
import com.suzhe.ymall.common.message.OrderSuccessMessage;
import com.suzhe.ymall.common.pojo.AppLoginUser;
import com.suzhe.ymall.common.utils.IdWorker;
import com.suzhe.ymall.common.utils.LoginUserUtils;
import com.suzhe.ymall.order.client.ProductClient;
import com.suzhe.ymall.order.client.PromotionClient;
import com.suzhe.ymall.order.enums.OrderStatusEnum;
import com.suzhe.ymall.order.mapper.OrderMapper;
import com.suzhe.ymall.order.param.SubmitOrderParam;
import com.suzhe.ymall.order.pojo.*;
import com.suzhe.ymall.order.service.*;
import com.suzhe.ymall.product.param.OrderSkuParam;
import com.suzhe.ymall.product.vo.SkuVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author suzhe
 * @since 2019-08-08
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private IdWorker idWorker;

    @Autowired
    ProductClient productClient;

    @Autowired
    PromotionClient promotionClient;

    @Autowired
    IShippingAddressService iShippingAddressService;

    @Autowired
    IOrderDetailService iOrderDetailService;

    @Autowired
    IOrderStatusService iOrderStatusService;

    @Autowired
    RocketMQTemplate rocketMQTemplate;

    @Autowired
    IMessageLogService iMessageLogService;


    @Transactional
    @Override
    public Order createOrder(SubmitOrderParam submitOrderParam) {
        //生成订单号
        String orderNo = idWorker.nextId();
        Order order = new Order();
        order.setOrderNo(orderNo);
        AppLoginUser appLoginUser = LoginUserUtils.getAppLoginUser();
        order.setUserId(appLoginUser.getId());
        List<OrderSkuParam> orderSkuParamList = submitOrderParam.getOrderSkuParamList();

        Map<Integer, Integer> skuNumMap = orderSkuParamList.stream().collect(Collectors.toMap(c -> c.getSkuId(), c -> c.getNum()));
        List<SkuVo> skuVos = productClient.querySkuVosByIds(new ArrayList<>(skuNumMap.keySet()));

        if (skuVos.isEmpty()) {
            log.error("查询商品失败:{}", orderSkuParamList);
            return null;
        }
        List<OrderDetail> orderDetails = new ArrayList<>();
        long totalPay = 0;
        for (SkuVo skuVo : skuVos) {
            Integer skuNum = skuNumMap.get(skuVo.getId());
            totalPay += skuVo.getPrice() * skuNum;
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setId(idWorker.nextId());
            orderDetail.setOrderNo(orderNo);
            orderDetail.setNum(skuNum);
            orderDetail.setSkuId(skuVo.getId());
            orderDetail.setTitle(skuVo.getTitle());
            orderDetail.setDescription(skuVo.getDesc());
            orderDetail.setPrice(skuVo.getPrice());
            orderDetail.setImgUrl(skuVo.getImgUrl());
            orderDetails.add(orderDetail);
        }
        order.setTotalPay(totalPay);
        order.setActualPay(totalPay);
        ShippingAddress shippingAddress = iShippingAddressService.getById(submitOrderParam.getShippingAddressId());
        order.setReceiverProvince(shippingAddress.getReceiverProvince());
        order.setReceiverCity(shippingAddress.getReceiverCity());
        order.setReceiverCounty(shippingAddress.getReceiverCounty());
        order.setReceiverAddress(shippingAddress.getReceiverAddress());
        order.setReceiverZip(shippingAddress.getReceiverZip());
        order.setReceiverMobile(shippingAddress.getReceiverMobile());
        order.setReceiver(shippingAddress.getReceiver());

        save(order);
        iOrderDetailService.saveBatch(orderDetails);

        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderNo(orderNo);
        orderStatus.setStatus(OrderStatusEnum.INVISIBLE.value());
        iOrderStatusService.save(orderStatus);
        return order;
    }

    @Override
    public boolean updateActualPay(String orderNo, Long actualPay) {
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setActualPay(actualPay);
        return updateById(order);
    }

    @Override
    public boolean updateOrderStatus(String orderNo, OrderStatusEnum orderStatusEnum) {
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderNo(orderNo);
        orderStatus.setStatus(orderStatusEnum.value());
        return iOrderStatusService.updateById(orderStatus);
    }

    @Override
    public void sendOrderRollbackMessage(String orderNo) {
        log.info("sendOrderRollbackMessage:{}", orderNo);
        OrderRollbackMessage messageData = new OrderRollbackMessage();
        messageData.setMessageId(idWorker.nextId());
        messageData.setOrderNo(orderNo);
        Message<OrderRollbackMessage> message = MessageBuilder.withPayload(messageData).build();
        rocketMQTemplate.asyncSend(TopicEnum.ORDER_ROLLBACK.value(), message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                //发送成功更新订单为ROLLBACK
                updateOrderStatus(orderNo,OrderStatusEnum.ROLLBACK);
            }
            @Override
            public void onException(Throwable e) {
                log.error("发送订单成功消息失败:{}",e);
            }
        });
    }

    @Override
    public void sendScheduledOrderMessage(String orderNo) {
        Message message = MessageBuilder.withPayload(orderNo).build();
        rocketMQTemplate.syncSend(TopicEnum.SCHEDULED_ORDER.value(),message,2000,14);
    }

    @Async("asyncServiceExecutor") //此处方法实现被加入到线程池中执行。当前的方法立刻返回，上级调用即可结束
    @Override
    public boolean paySuccess(String messageId,String orderNo) {
        OrderStatus orderStatus = iOrderStatusService.getById(orderNo);
        if (OrderStatusEnum.INIT.value().equals(orderStatus.getStatus())){
            orderStatus.setStatus(OrderStatusEnum.PAY_UP.value());
            orderStatus.setPaymentTime(new Date());
            iOrderStatusService.updateById(orderStatus);

            OrderSuccessMessage orderSuccessMessage = new OrderSuccessMessage();
            orderSuccessMessage.setMessageId(messageId);
            orderSuccessMessage.setOrderNo(orderNo);
            Message<OrderSuccessMessage> message = MessageBuilder.withPayload(orderSuccessMessage).build();
            rocketMQTemplate.asyncSend(TopicEnum.ORDER_SUCCESS.value(), message, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    //发送成功更新 消息日志为Done
                    updateMessageStatus(messageId,MessageStatusEnum.DONE);
                }
                @Override
                public void onException(Throwable e) {
                    log.error("发送订单成功消息失败:{}",e);
                }
            });
        }
        return true;
    }

    @Override
    public boolean updateMessageStatus(String messageId, MessageStatusEnum messageStatusEnum) {
        MessageLog messageLog = new MessageLog();
        messageLog.setId(messageId);
        messageLog.setStatus(messageStatusEnum.value());
        return iMessageLogService.updateById(messageLog);
    }

}
